<?php declare(strict_types=1);
/**
 * This file is part of Swoft.
 *
 * @link     https://swoft.org
 * @document https://swoft.org/docs
 * @contact  group@swoft.org
 * @license  https://github.com/swoft-cloud/swoft/blob/master/LICENSE
 */

namespace App\Exception\Handler;

use App\Library\Core\ErrCode;
use Swoft\Error\Annotation\Mapping\ExceptionHandler;
use Swoft\Http\Message\ContentType;
use Swoft\Http\Message\Response;
use Swoft\Http\Server\Exception\Handler\AbstractHttpErrorHandler;
use Swoft\Log\Helper\CLog;
use Swoft\Log\Helper\Log;
use function Swoole\Coroutine\Http\request;
use Throwable;
use function get_class;
use function sprintf;
use const APP_DEBUG;

/**
 * Class HttpExceptionHandler
 *
 * @ExceptionHandler(\Throwable::class)
 */
class HttpExceptionHandler extends AbstractHttpErrorHandler
{
    /**
     * @param Throwable $e
     * @param Response  $response
     *
     * @return Response
     */
    public function handle(Throwable $e, Response $response): Response
    {
        // Log error message
        Log::error('(exception:%s) %s At %s line %d trace:%s',get_class($e),$e->getMessage(),$e->getFile(),$e->getLine(),$e->getTraceAsString());
        switch (get_class($e)){
            case 'Swoft\\Validator\\Exception\\ValidatorException': //参数验证异常
                $code = ErrCode::PARAM_VALIDATE_ERROR;;
                $msg = ErrCode::msg(ErrCode::PARAM_VALIDATE_ERROR);
                $error = $e->getMessage();
                break;
            case 'Error': //返回异常【限流导致】
                $code = ErrCode::RESPONSE_ERR;
                $msg = ErrCode::msg(ErrCode::RESPONSE_ERR);
                $error =  $e->getMessage();
                break;
            default: //系统异常
                $code = ErrCode::ERR_SYSTEM;
                $msg = ErrCode::msg(ErrCode::ERR_SYSTEM);
                $error = $e->getMessage();//sprintf('(%s) %s', get_class($e), $e->getMessage());
        }
            $data = [
                'code'  => $code,
                'msg'   => $msg,
                'error' => $error,
                'file'  => sprintf('At %s line %d', $e->getFile(), $e->getLine()),
            ];

        // Debug is true
        return $response
            ->withHeader('Access-Control-Allow-Credentials',true)
            ->withHeader('Access-Control-Allow-Origin', '*')
            ->withHeader('Access-Control-Allow-Headers' , 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,x-Vendor-Authorization,X-Vendor-Host,x-XT-Authorization')
            ->withContentType(ContentType::JSON)
            ->withData($data);
    }
}
